home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / Interfaces&Libraries / Universal / Interfaces / CIncludes / PEFBinaryFormat.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-12  |  49.4 KB  |  1,139 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        PEFBinaryFormat.h
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    Universal Interfaces 3.0.1
  8.  
  9.      Copyright:    © 1993-1997 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        Please include the the file and version information (from above) with
  12.                  the problem description.  Developers belonging to one of the Apple
  13.                  developer programs can submit bug reports to:
  14.  
  15.                      devsupport@apple.com
  16.  
  17. */
  18.  
  19.  
  20. #ifndef __PEFBINARYFORMAT__
  21. #define __PEFBINARYFORMAT__
  22.  
  23. #ifndef __TYPES__
  24. #include <Types.h>
  25. #endif
  26.  
  27.  
  28.  
  29. #if PRAGMA_ONCE
  30. #pragma once
  31. #endif
  32.  
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36.  
  37. #if PRAGMA_IMPORT
  38. #pragma import on
  39. #endif
  40.  
  41. #if PRAGMA_STRUCT_ALIGN
  42.     #pragma options align=mac68k
  43. #elif PRAGMA_STRUCT_PACKPUSH
  44.     #pragma pack(push, 2)
  45. #elif PRAGMA_STRUCT_PACK
  46.     #pragma pack(2)
  47. #endif
  48.  
  49.  
  50. /* -----------------------------------------------------------------------------------------    */
  51. /* Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    */
  52. /* 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        */
  53. /* packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        */
  54. /* ensure consistent treatment across compilers.                                                */
  55.  
  56.  
  57.  
  58. /* ======================================================================================== */
  59. /* Overall Structure */
  60. /* ================= */
  61.  
  62.  
  63.  
  64. /* -------------------------------------------------------------------------------------------    */
  65. /* This header contains a complete set of types and macros for dealing with the PEF executable    */
  66. /* format.  While some description is provided, this header is not meant as a primary source    */
  67. /* of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    */
  68. /* Runtime Architectures book.  This header is primarily a physical format description.  Thus    */
  69. /* it depends on as few other headers as possible and structure fields have obvious sizes.        */
  70. /*                                                                                                 */
  71. /* The physical storage for a PEF executable is known as a "container".  This refers to just    */
  72. /* the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    */
  73. /* data fork, that one data fork has five containers within it.                                    */
  74. /*                                                                                                 */
  75. /* A PEF container consists of an overall header, followed by one or more section headers,        */
  76. /* followed by the section name table, followed by the contents for the sections.  Some kinds    */
  77. /* of sections have specific internal representation.  The "loader" section is the most common    */
  78. /* of these special sections.  It contains information on the exports, imports, and runtime        */
  79. /* relocations required to prepare the executable.  PEF containers are self contained, all        */
  80. /* portions are located via relative offsets.                                                    */
  81. /*                                                                                                 */
  82. /*                                                                                                 */
  83. /*            +-------------------------------+                                                    */
  84. /*            |        Container Header        |    40 bytes                                        */
  85. /*            +-------------------------------+                                                    */
  86. /*            |        Section 0 header        |    28 bytes each                                    */
  87. /*            |...............................|                                                    */
  88. /*            |            - - - -                |                                                    */
  89. /*            |...............................|                                                    */
  90. /*            |        Section n-1 header        |                                                    */
  91. /*            +-------------------------------+                                                    */
  92. /*            |        Section Name Table        |                                                    */
  93. /*            +-------------------------------+                                                    */
  94. /*            |        Section x raw data        |                                                    */
  95. /*            +-------------------------------+                                                    */
  96. /*             |            - - - -                |                                                    */
  97. /*            +-------------------------------+                                                    */
  98. /*            |        Section y raw data        |                                                    */
  99. /*            +-------------------------------+                                                    */
  100. /*                                                                                                 */
  101. /*                                                                                                 */
  102. /* The sections are implicitly numbered from 0 to n according to the order of their headers.    */
  103. /* The headers of the instantiated sections must precede those of the non-instantiated            */
  104. /* sections.  The ordering of the raw data is independent of the section header ordering.        */
  105. /* Each section header contains the offset for that section's raw data.                            */
  106.  
  107.  
  108.  
  109. /* =========================================================================================== */
  110. /* Container Header */
  111. /* ================ */
  112.  
  113.  
  114.  
  115. struct PEFContainerHeader {
  116.     OSType                             tag1;                        /* Must contain 'Joy!'. */
  117.     OSType                             tag2;                        /* Must contain 'peff'.  (Yes, with two 'f's.) */
  118.     OSType                             architecture;                /* The ISA for code sections.  Constants in CodeFragments.h. */
  119.     UInt32                             formatVersion;                /* The physical format version. */
  120.     UInt32                             dateTimeStamp;                /* Macintosh format creation/modification stamp. */
  121.     UInt32                             oldDefVersion;                /* Old definition version number for the code fragment. */
  122.     UInt32                             oldImpVersion;                /* Old implementation version number for the code fragment. */
  123.     UInt32                             currentVersion;                /* Current version number for the code fragment. */
  124.     UInt16                             sectionCount;                /* Total number of section headers that follow. */
  125.     UInt16                             instSectionCount;            /* Number of instantiated sections. */
  126.     UInt32                             reservedA;                    /* Reserved, must be written as zero. */
  127. };
  128. typedef struct PEFContainerHeader PEFContainerHeader;
  129.  
  130.  
  131. enum {
  132.     kPEFTag1                    = FOUR_CHAR_CODE('Joy!'),        /* For non-Apple compilers: 0x4A6F7921. */
  133.     kPEFTag2                    = FOUR_CHAR_CODE('peff'),        /* For non-Apple compilers: 0x70656666. */
  134.     kPEFVersion                    = 0x00000001
  135. };
  136.  
  137.  
  138.  
  139. enum {
  140.     kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  141. };
  142.  
  143. #define PEFFirstSectionNameOffset(container)    \
  144.             ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  145.  
  146.  
  147.  
  148. /* =========================================================================================== */
  149. /* Section Headers */
  150. /* =============== */
  151.  
  152.  
  153.  
  154. struct PEFSectionHeader {
  155.     SInt32                             nameOffset;                    /* Offset of name within the section name table, -1 => none. */
  156.     UInt32                             defaultAddress;                /* Default address, affects relocations. */
  157.     UInt32                             totalLength;                /* Fully expanded size in bytes of the section contents. */
  158.     UInt32                             unpackedLength;                /* Size in bytes of the "initialized" part of the contents. */
  159.     UInt32                             containerLength;            /* Size in bytes of the raw data in the container. */
  160.     UInt32                             containerOffset;            /* Offset of section's raw data. */
  161.     UInt8                             sectionKind;                /* Kind of section contents/usage. */
  162.     UInt8                             shareKind;                    /* Sharing level, if a writeable section. */
  163.     UInt8                             alignment;                    /* Preferred alignment, expressed as log 2. */
  164.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  165. };
  166. typedef struct PEFSectionHeader PEFSectionHeader;
  167.  
  168.  
  169. enum {
  170.                                                                 /* Values for the sectionKind field. */
  171.                                                                 /*    Section kind values for instantiated sections. */
  172.     kPEFCodeSection                = 0,                            /* Code, presumed pure & position independent. */
  173.     kPEFUnpackedDataSection        = 1,                            /* Unpacked writeable data. */
  174.     kPEFPackedDataSection        = 2,                            /* Packed writeable data. */
  175.     kPEFConstantSection            = 3,                            /* Read-only data. */
  176.     kPEFExecDataSection            = 6,                            /* Intermixed code and writeable data. */
  177.                                                                 /* Section kind values for non-instantiated sections. */
  178.     kPEFLoaderSection            = 4,                            /* Loader tables. */
  179.     kPEFDebugSection            = 5,                            /* Reserved for future use. */
  180.     kPEFExceptionSection        = 7,                            /* Reserved for future use. */
  181.     kPEFTracebackSection        = 8                                /* Reserved for future use. */
  182. };
  183.  
  184.  
  185.  
  186. enum {
  187.                                                                 /* Values for the shareKind field. */
  188.     kPEFProcessShare            = 1,                            /* Shared within a single process. */
  189.     kPEFGlobalShare                = 4,                            /* Shared across the entire system. */
  190.     kPEFProtectedShare            = 5                                /* Readable across the entire system, writeable only to privileged code. */
  191. };
  192.  
  193.  
  194.  
  195.  
  196. /* =========================================================================================== */
  197. /* Packed Data Contents */
  198. /* ==================== */
  199.  
  200.  
  201.  
  202. /* -------------------------------------------------------------------------------------------    */
  203. /* The raw contents of a packed data section are a sequence of byte codes.  The basic format    */
  204. /* has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        */
  205. /* counts larger than 31, and to contain a second or third count.  Further additional bytes        */
  206. /* contain actual data values to transfer.                                                        */
  207. /*                                                                                                 */
  208. /* All counts are represented in a variable length manner.  A zero in the initial 5 bit count    */
  209. /* indicates the actual value follows.  In this case, and for the second and third counts, the    */
  210. /* count is represented as a variable length sequence of bytes.  The bytes are stored in big    */
  211. /* endian manner, most significant part first.  The high order bit is set in all but the last    */
  212. /* byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    */
  213. /* low order 7 bits of the next byte.                                                            */
  214.  
  215.  
  216.  
  217. enum {
  218.                                                                 /* The packed data opcodes. */
  219.     kPEFPkDataZero                = 0,                            /* Zero fill "count" bytes. */
  220.     kPEFPkDataBlock                = 1,                            /* Block copy "count" bytes. */
  221.     kPEFPkDataRepeat            = 2,                            /* Repeat "count" bytes "count2"+1 times. */
  222.     kPEFPkDataRepeatBlock        = 3,                            /* Interleaved repeated and unique data. */
  223.     kPEFPkDataRepeatZero        = 4                                /* Interleaved zero and unique data. */
  224. };
  225.  
  226.  
  227.  
  228. enum {
  229.     kPEFPkDataOpcodeShift        = 5,
  230.     kPEFPkDataCount5Mask        = 0x1F,
  231.     kPEFPkDataMaxCount5            = 31,
  232.     kPEFPkDataVCountShift        = 7,
  233.     kPEFPkDataVCountMask        = 0x7F,
  234.     kPEFPkDataVCountEndMask        = 0x80
  235. };
  236.  
  237.  
  238. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  239.  
  240. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  241.  
  242. #define PEFPkDataComposeInstr(opcode,count5)        \
  243.             ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  244.  
  245.  
  246.  
  247. /* ------------------------------------------------------------------------------------------    */
  248. /* The following code snippet can be used to input a variable length count.                        */
  249. /*                                                                                                 */
  250. /*        count = 0;                                                                                */
  251. /*        do {                                                                                    */
  252. /*            byte = *bytePtr++;                                                                    */
  253. /*            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            */
  254. /*        } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        */
  255. /*                                                                                                 */
  256. /* The following code snippet can be used to output a variable length count to a byte array.    */
  257. /* This is more complex than the input code because the chunks are output in big endian order.    */
  258. /* Think about handling values like 0 or 0x030000.                                                */
  259. /*                                                                                                 */
  260. /*        count = 1;.                                                                                */
  261. /*        tempValue = value >> kPEFPkDataCountShift;                                                */
  262. /*        while ( tempValue != 0 ) {                                                                */
  263. /*            count += 1;                                                                            */
  264. /*            tempValue = tempValue >> kPEFPkDataCountShift;                                        */
  265. /*        }                                                                                        */
  266. /*                                                                                                 */
  267. /*        bytePtr += count;                                                                        */
  268. /*        tempPtr = bytePtr - 1;                                                                    */
  269. /*        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        */
  270. /*        for ( count -= 1; count != 0; count -= 1 ) {                                            */
  271. /*            value = value >> kPEFPkDataCountShift;                                                */
  272. /*            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        */
  273. /*        }                                                                                        */
  274.  
  275.  
  276.  
  277. /* =========================================================================================== */
  278. /* Loader Section */
  279. /* ============== */
  280.  
  281.  
  282.  
  283. /* ------------------------------------------------------------------------------------------    */
  284. /* The loader section contains information needed to prepare the code fragment for execution.    */
  285. /* This includes this fragment's exports, the import libraries and the imported symbols from    */
  286. /* each library, and the relocations for the writeable sections.                                */
  287. /*                                                                                                 */
  288. /*            +-----------------------------------+                <-- containerOffset --------+    */
  289. /*            |        Loader Info Header            |    56 bytes                                |    */
  290. /*            |-----------------------------------|                                            |    */
  291. /*            |        Imported Library 0            |    24 bytes each                            |    */
  292. /*            |...................................|                                            |    */
  293. /*            |            - - -                    |                                            |    */
  294. /*            |...................................|                                            |    */
  295. /*            |        Imported Library l-1        |                                            |    */
  296. /*            |-----------------------------------|                                            |    */
  297. /*            |        Imported Symbol 0            |    4 bytes each                            |    */
  298. /*            |...................................|                                            |    */
  299. /*            |            - - -                    |                                            |    */
  300. /*            |...................................|                                            |    */
  301. /*            |         Imported Symbol i-1            |                                            |    */
  302. /*            |-----------------------------------|                                            |    */
  303. /*            |        Relocation Header 0            |    12 bytes each                            |    */
  304. /*            |...................................|                                            |    */
  305. /*            |            - - -                    |                                            |    */
  306. /*            |...................................|                                            |    */
  307. /*            |        Relocation Header r-1        |                                            |    */
  308. /*            |-----------------------------------|                <-- + relocInstrOffset -----|    */
  309. /*            |        Relocation Instructions        |                                            |    */
  310. /*            |-----------------------------------|                <-- + loaderStringsOffset --|    */
  311. /*            |        Loader String Table            |                                            |    */
  312. /*            |-----------------------------------|                <-- + exportHashOffset -----+    */
  313. /*            |        Export Hash Slot 0            |    4 bytes each                                */
  314. /*            |...................................|                                                */
  315. /*            |            - - -                    |                                                */
  316. /*            |...................................|                                                */
  317. /*            |         Export Hash Slot h-1        |                                                */
  318. /*            |-----------------------------------|                                                */
  319. /*            |        Export Symbol Key 0            |    4 bytes each                                */
  320. /*            |...................................|                                                */
  321. /*            |            - - -                    |                                                */
  322. /*            |...................................|                                                */
  323. /*            |        Export Symbol Key e-1        |                                                */
  324. /*            |-----------------------------------|                                                */
  325. /*            |        Export Symbol 0                |    10 bytes each                                */
  326. /*            |...................................|                                                */
  327. /*            |            - - -                    |                                                */
  328. /*            |...................................|                                                */
  329. /*            |        Export Symbol e-1            |                                                */
  330. /*            +-----------------------------------+                                                */
  331.  
  332.  
  333.  
  334. struct PEFLoaderInfoHeader {
  335.     SInt32                             mainSection;                /* Section containing the main symbol, -1 => none. */
  336.     UInt32                             mainOffset;                    /* Offset of main symbol. */
  337.     SInt32                             initSection;                /* Section containing the init routine's TVector, -1 => none. */
  338.     UInt32                             initOffset;                    /* Offset of the init routine's TVector. */
  339.     SInt32                             termSection;                /* Section containing the term routine's TVector, -1 => none. */
  340.     UInt32                             termOffset;                    /* Offset of the term routine's TVector. */
  341.     UInt32                             importedLibraryCount;        /* Number of imported libraries.  ('l') */
  342.     UInt32                             totalImportedSymbolCount;    /* Total number of imported symbols.  ('i') */
  343.     UInt32                             relocSectionCount;            /* Number of sections with relocations.  ('r') */
  344.     UInt32                             relocInstrOffset;            /* Offset of the relocation instructions. */
  345.     UInt32                             loaderStringsOffset;        /* Offset of the loader string table. */
  346.     UInt32                             exportHashOffset;            /* Offset of the export hash table. */
  347.     UInt32                             exportHashTablePower;        /* Export hash table size as log 2.  (Log2('h')) */
  348.     UInt32                             exportedSymbolCount;        /* Number of exported symbols.  ('e') */
  349. };
  350. typedef struct PEFLoaderInfoHeader PEFLoaderInfoHeader;
  351.  
  352.  
  353.  
  354. /* =========================================================================================== */
  355. /* Imported Libraries */
  356. /* ------------------ */
  357.  
  358.  
  359. struct PEFImportedLibrary {
  360.     UInt32                             nameOffset;                    /* Loader string table offset of library's name. */
  361.     UInt32                             oldImpVersion;                /* Oldest compatible implementation version. */
  362.     UInt32                             currentVersion;                /* Current version at build time. */
  363.     UInt32                             importedSymbolCount;        /* Imported symbol count for this library. */
  364.     UInt32                             firstImportedSymbol;        /* Index of first imported symbol from this library. */
  365.     UInt8                             options;                    /* Option bits for this library. */
  366.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  367.     UInt16                             reservedB;                    /* Reserved, must be zero. */
  368. };
  369. typedef struct PEFImportedLibrary PEFImportedLibrary;
  370.  
  371.  
  372. enum {
  373.                                                                 /* Bits for the PEFImportedLibrary options field. */
  374.     kPEFWeakImportLibMask        = 0x40,                            /* The imported library is allowed to be missing. */
  375.     kPEFInitLibBeforeMask        = 0x80                            /* The imported library must be initialized first. */
  376. };
  377.  
  378.  
  379.  
  380.  
  381. /* =========================================================================================== */
  382. /* Imported Symbols */
  383. /* ---------------- */
  384.  
  385.  
  386.  
  387. /* -------------------------------------------------------------------------------------------    */
  388. /* The PEFImportedSymbol type has the following bit field layout.                                */
  389. /*                                                                                                 */
  390. /*                                                                       3                        */
  391. /*         0             7 8                                             1                        */
  392. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  393. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  394. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  395. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  396.  
  397.  
  398.  
  399. struct PEFImportedSymbol {
  400.     UInt32                             classAndName;
  401. };
  402. typedef struct PEFImportedSymbol PEFImportedSymbol;
  403.  
  404.  
  405. enum {
  406.     kPEFImpSymClassShift        = 24,
  407.     kPEFImpSymNameOffsetMask    = 0x00FFFFFF,
  408.     kPEFImpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  409. };
  410.  
  411. #define PEFImportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  412. #define PEFImportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFImpSymNameOffsetMask)
  413.  
  414. #define PEFComposeImportedSymbol(class,nameOffset)        \
  415.             ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  416.  
  417.  
  418. enum {
  419.                                                                 /* Imported and exported symbol classes. */
  420.     kPEFCodeSymbol                = 0x00,
  421.     kPEFDataSymbol                = 0x01,
  422.     kPEFTVectorSymbol            = 0x02,
  423.     kPEFTOCSymbol                = 0x03,
  424.     kPEFGlueSymbol                = 0x04,
  425.     kPEFUndefinedSymbol            = 0x0F,
  426.     kPEFWeakImportSymMask        = 0x80
  427. };
  428.  
  429.  
  430.  
  431.  
  432. /* =========================================================================================== */
  433. /* Exported Symbol Hash Table */
  434. /* -------------------------- */
  435.  
  436.  
  437.  
  438. /* -------------------------------------------------------------------------------------------    */
  439. /* Exported symbols are described in four parts, optimized for speed of lookup.  These parts    */
  440. /* are the "export hash table", the "export key table", the "export symbol table", and the        */
  441. /* "export name table".  Overall they contain a flattened representation of a fairly normal        */
  442. /* hashed symbol table.                                                                            */
  443. /*                                                                                                */
  444. /* The export hash table is an array of small fixed size elements.  The number of elements is    */
  445. /* a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    */
  446. /* Each hash slot contains a count of the number of exported symbols that map to this slot and    */
  447. /* the index of the first of those symbols in the key and symbol tables.  Of course some hash    */
  448. /* slots will have a zero count.                                                                */
  449. /*                                                                                                */
  450. /* The key and symbol tables are also arrays of fixed size elements, one for each exported        */
  451. /* symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        */
  452. /* slot are contiguous.  The key table contains just the full 32 bit hash word for each            */
  453. /* exported symbol.  The symbol table contains the offset of the symbol's name in the string    */
  454. /* table and other information about the exported symbol.                                        */
  455. /*                                                                                                */
  456. /* To look up an export you take the hashword and compute the hash slot index.  You then scan    */
  457. /* the indicated portion of the key table for matching hashwords.  If a hashword matches, you    */
  458. /* look at the corresponding symbol table entry to find the full symbol name.  If the names        */
  459. /* match the symbol is found.                                                                    */
  460.  
  461.  
  462.  
  463. /* -------------------------------------------------------------------------------------------    */
  464. /* The following function may be used to compute the hash table size.  Signed values are used    */
  465. /* just to avoid potential code generation overhead for unsigned division.                        */
  466. /*                                                                                                 */
  467. /*        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            */
  468. /*        {                                                                                        */
  469. /*            SInt32    exponent;                                                                    */
  470. /*                                                                                                 */
  471. /*            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    */
  472. /*            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    */
  473. /*                                                                                                 */
  474. /*            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    */
  475. /*                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                */
  476. /*            }                                                                                    */
  477. /*                                                                                                 */
  478. /*            return exponent;                                                                    */
  479. /*                                                                                                 */
  480. /*        }    // PEFComputeHashTableExponent ()                                                    */
  481.  
  482.  
  483.  
  484. /* -------------------------------------------------------------------------------------------    */
  485. /* The PEFExportedSymbolHashSlot type has the following bit field layout.                        */
  486. /*                                                                                                 */
  487. /*                                   1 1                                 3                        */
  488. /*         0                         3 4                                 1                        */
  489. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  490. /*        | symbol count              | index of first export key         |                        */
  491. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  492. /*        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        */
  493.  
  494.  
  495.  
  496. struct PEFExportedSymbolHashSlot {
  497.     UInt32                             countAndStart;
  498. };
  499. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  500.  
  501.  
  502. enum {
  503.     kPEFHashSlotSymCountShift    = 18,
  504.     kPEFHashSlotFirstKeyMask    = 0x0003FFFF,
  505.     kPEFHashSlotMaxSymbolCount    = 0x00003FFF,                    /*  16,383 */
  506.     kPEFHashSlotMaxKeyIndex        = 0x0003FFFF                    /* 262,143 */
  507. };
  508.  
  509. #define PEFHashTableIndex(fullHashWord,hashTablePower)    \
  510.             ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  511.  
  512. #define PEFHashSlotSymbolCount(countAndStart)    ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  513. #define PEFHashSlotFirstKey(countAndStart)        ((countAndStart) & kPEFHashSlotFirstKeyMask)
  514.  
  515. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey)    \
  516.             ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  517.  
  518.  
  519.  
  520. /* =========================================================================================== */
  521. /* Exported Symbol Hash Key */
  522. /* ------------------------ */
  523.  
  524.  
  525.  
  526. struct PEFSplitHashWord {
  527.     UInt16                             nameLength;
  528.     UInt16                             hashValue;
  529. };
  530. typedef struct PEFSplitHashWord PEFSplitHashWord;
  531.  
  532. struct PEFExportedSymbolKey {
  533.     union {
  534.         UInt32                             fullHashWord;
  535.         PEFSplitHashWord                 splitHashWord;
  536.     }                                 u;
  537. };
  538. typedef struct PEFExportedSymbolKey PEFExportedSymbolKey;
  539.  
  540.  
  541. enum {
  542.     kPEFHashLengthShift            = 16,
  543.     kPEFHashValueMask            = 0x0000FFFF,
  544.     kPEFHashMaxLength            = 0x0000FFFF                    /* 65,535 */
  545. };
  546.  
  547. #define PEFHashNameLength(fullHashWord)    ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  548. #define PEFHashValue(fullHashWord)    ((fullHashWord) & kPEFHashValueMask)
  549.  
  550. #define PEFComposeFullHashWord(nameLength,hashValue)    \
  551.             ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  552.  
  553.  
  554.  
  555. /* -------------------------------------------------------------------------------------------            */
  556. /* The following function computes the full 32 bit hash word.                                            */
  557. /*                                                                                                         */
  558. /*        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    */
  559. /*                                      UInt32    nameLength )    // ! The text may be zero terminated.    */
  560. /*        {                                                                                                */
  561. /*            BytePtr    charPtr        = nameText;                                                                */
  562. /*            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                */
  563. /*            UInt32    length        = 0;                                                                    */
  564. /*            UInt32    limit;                                                                                */
  565. /*            UInt32    result;                                                                                */
  566. /*            UInt8    currChar;                                                                            */
  567. /*                                                                                                         */
  568. /*            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    */
  569. /*                                                                                                         */
  570. /*            for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            */
  571. /*                currChar = *charPtr++;                                                                    */
  572. /*                if ( currChar == NULL ) break;                                                            */
  573. /*                length += 1;                                                                            */
  574. /*                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        */
  575. /*            }                                                                                            */
  576. /*                                                                                                         */
  577. /*            result    = (length << kPEFHashLengthShift) |                                                    */
  578. /*                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    */
  579. /*                                                                                                         */
  580. /*            return result;                                                                                */
  581. /*                                                                                                         */
  582. /*        }    // PEFComputeHashWord ()                                                                    */
  583.  
  584.  
  585.  
  586. /* =========================================================================================== */
  587. /* Exported Symbols */
  588. /* ---------------- */
  589.  
  590.  
  591.  
  592. struct PEFExportedSymbol {                                        /* ! This structure is 10 bytes long and arrays are packed. */
  593.     UInt32                             classAndName;                /* A combination of class and name offset. */
  594.     UInt32                             symbolValue;                /* Typically the symbol's offset within a section. */
  595.     SInt16                             sectionIndex;                /* The index of the section, or pseudo-section, for the symbol. */
  596. };
  597. typedef struct PEFExportedSymbol PEFExportedSymbol;
  598.  
  599.  
  600. /* -------------------------------------------------------------------------------------------    */
  601. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout.        */
  602. /*                                                                                                 */
  603. /*                                                                       3                        */
  604. /*         0             7 8                                             1                        */
  605. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  606. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  607. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  608. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  609.  
  610.  
  611.  
  612. enum {
  613.     kPEFExpSymClassShift        = 24,
  614.     kPEFExpSymNameOffsetMask    = 0x00FFFFFF,
  615.     kPEFExpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  616. };
  617.  
  618. #define PEFExportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  619. #define PEFExportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFExpSymNameOffsetMask)
  620.  
  621. #define PEFComposeExportedSymbol(class,nameOffset)        \
  622.             ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  623.  
  624.  
  625. enum {
  626.                                                                 /* Negative section indices indicate pseudo-sections. */
  627.     kPEFAbsoluteExport            = -2,                            /* The symbol value is an absolute address. */
  628.     kPEFReexportedImport        = -3                            /* The symbol value is the index of a reexported import. */
  629. };
  630.  
  631.  
  632.  
  633.  
  634. /* =========================================================================================== */
  635. /* Loader Relocations */
  636. /* ================== */
  637.  
  638.  
  639.  
  640. /* -------------------------------------------------------------------------------------------    */
  641. /* The relocations for a section are defined by a sequence of instructions for an abstract        */
  642. /* machine that is specifically geared to performing relocations commonly needed for the "CFM"    */
  643. /* code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    */
  644. /* just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    */
  645. /* the operands in the first chunk, with other operands in following chunks.                    */
  646.  
  647.  
  648.  
  649. typedef UInt16                             PEFRelocChunk;
  650. struct PEFLoaderRelocationHeader {
  651.     UInt16                             sectionIndex;                /* Index of the section to be fixed up. */
  652.     UInt16                             reservedA;                    /* Reserved, must be zero. */
  653.     UInt32                             relocCount;                    /* Number of 16 bit relocation chunks. */
  654.     UInt32                             firstRelocOffset;            /* Offset of first relocation instruction. */
  655. };
  656. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  657.  
  658.  
  659. /* -------------------------------------------------------------------------------------------    */
  660. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        */
  661. /* ! total number of bytes of relocation instructions.  While most relocation instructions are    */
  662. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be        */
  663. /* ! less than the relocCount value.                                                            */
  664.  
  665.  
  666.  
  667. /* ----------------------------------------------------------------------------------    */
  668. /* The PEFRelocField macro is a utility for extracting relocation instruction fields.    */
  669.  
  670.  
  671. #define PEFRFShift(offset,length)    (16 - (offset + length))
  672. #define PEFRFMask(length)            ((1 << length) - 1)
  673.  
  674. #define PEFRelocField(chunk,offset,length)    \
  675.             ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  676.  
  677.  
  678.  
  679. /* =========================================================================================== */
  680. /* Basic Relocation Opcodes */
  681. /* ------------------------ */
  682.  
  683.  
  684. /* ------------------------------------------------------------------------------------------    */
  685. /* The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    */
  686. /* are defined in terms of the most significant 7 bits of the first instruction chunk.  An        */
  687. /* instruction is decoded by using the most significant 7 bits as an index into the opcode        */
  688. /* table, which in turn contains appropriately masked forms of the most significant 7 bits.        */
  689. /* The macro PEFRelocBasicOpcode assumes a declaration of the form.                                */
  690. /*                                                                                                 */
  691. /*        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    */
  692.  
  693.  
  694.  
  695. enum {
  696.     kPEFRelocBasicOpcodeRange    = 128
  697. };
  698.  
  699. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  700.  
  701.  
  702.  
  703. /* -------------------------------------------------------------------------------------------    */
  704. /* The relocation opcodes, clustered by major and minor groups.  The instructions within a        */
  705. /* cluster all have the same bit field layout.  The enumeration values use the high order 7        */
  706. /* bits of the relocation instruction.  Unused low order bits are set to zero.                    */
  707.  
  708.  
  709. enum {
  710.     kPEFRelocBySectDWithSkip    = 0x00,                            /* Binary: 00x_xxxx */
  711.     kPEFRelocBySectC            = 0x20,                            /* Binary: 010_0000, group is "RelocRun" */
  712.     kPEFRelocBySectD            = 0x21,                            /* Binary: 010_0001 */
  713.     kPEFRelocTVector12            = 0x22,                            /* Binary: 010_0010 */
  714.     kPEFRelocTVector8            = 0x23,                            /* Binary: 010_0011 */
  715.     kPEFRelocVTable8            = 0x24,                            /* Binary: 010_0100 */
  716.     kPEFRelocImportRun            = 0x25,                            /* Binary: 010_0101 */
  717.     kPEFRelocSmByImport            = 0x30,                            /* Binary: 011_0000, group is "RelocSmIndex" */
  718.     kPEFRelocSmSetSectC            = 0x31,                            /* Binary: 011_0001 */
  719.     kPEFRelocSmSetSectD            = 0x32,                            /* Binary: 011_0010 */
  720.     kPEFRelocSmBySection        = 0x33,                            /* Binary: 011_0011 */
  721.     kPEFRelocIncrPosition        = 0x40,                            /* Binary: 100_0xxx */
  722.     kPEFRelocSmRepeat            = 0x48,                            /* Binary: 100_1xxx */
  723.     kPEFRelocSetPosition        = 0x50,                            /* Binary: 101_000x */
  724.     kPEFRelocLgByImport            = 0x52,                            /* Binary: 101_001x */
  725.     kPEFRelocLgRepeat            = 0x58,                            /* Binary: 101_100x */
  726.     kPEFRelocLgSetOrBySection    = 0x5A,                            /* Binary: 101_101x */
  727.     kPEFRelocUndefinedOpcode    = 0xFF                            /* Used in masking table for all undefined values. */
  728. };
  729.  
  730.  
  731.  
  732. /* ----------------------------------------------------------------------------    */
  733. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode.    */
  734.  
  735.  
  736. enum {
  737.     kPEFRelocLgBySectionSubopcode = 0x00,                        /* Binary: 0000 */
  738.     kPEFRelocLgSetSectCSubopcode = 0x01,                        /* Binary: 0001 */
  739.     kPEFRelocLgSetSectDSubopcode = 0x02                            /* Binary: 0010 */
  740. };
  741.  
  742. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  743.  
  744.  
  745.  
  746. /* ------------------------------------------------------------------------------------------    */
  747. /* The initial values for the opcode "masking" table.  This has the enumeration values from        */
  748. /* above with appropriate replications for "don't care" bits.  It is almost certainly shorter    */
  749. /* and faster to look up the masked value in a table than to use a branch tree.                    */
  750.  
  751.  
  752. #define PEFMaskedBasicOpcodes                                                                                                                    \
  753.                                                                                                                                                 \
  754.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x00 .. 0x03 */    \
  755.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x04 .. 0x07 */    \
  756.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x08 .. 0x0B */    \
  757.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x0C .. 0x0F */    \
  758.                                                                                                                                                 \
  759.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x10 .. 0x13 */    \
  760.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x14 .. 0x17 */    \
  761.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x18 .. 0x1B */    \
  762.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x1C .. 0x1F */    \
  763.                                                                                                                                                 \
  764.             kPEFRelocBySectC,            kPEFRelocBySectD,            kPEFRelocTVector12,            kPEFRelocTVector8,            /* 0x20 .. 0x23 */    \
  765.             kPEFRelocVTable8,            kPEFRelocImportRun,            kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x24 .. 0x27 */    \
  766.                                                                                                                                                 \
  767.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x28 .. 0x2B */    \
  768.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x2C .. 0x2F */    \
  769.                                                                                                                                                 \
  770.             kPEFRelocSmByImport,        kPEFRelocSmSetSectC,        kPEFRelocSmSetSectD,        kPEFRelocSmBySection,        /* 0x30 .. 0x33 */    \
  771.                                                                                                                                                 \
  772.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x34 .. 0x37 */    \
  773.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x38 .. 0x3B */    \
  774.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x3C .. 0x3F */    \
  775.                                                                                                                                                 \
  776.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x40 .. 0x43 */    \
  777.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x44 .. 0x47 */    \
  778.                                                                                                                                                 \
  779.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x48 .. 0x4B */    \
  780.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x4C .. 0x4F */    \
  781.                                                                                                                                                 \
  782.             kPEFRelocSetPosition,        kPEFRelocSetPosition,        kPEFRelocLgByImport,        kPEFRelocLgByImport,        /* 0x50 .. 0x53 */    \
  783.                                                                                                                                                 \
  784.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x54 .. 0x57 */    \
  785.                                                                                                                                                 \
  786.             kPEFRelocLgRepeat,            kPEFRelocLgRepeat,            kPEFRelocLgSetOrBySection,    kPEFRelocLgSetOrBySection,    /* 0x58 .. 0x5B */    \
  787.                                                                                                                                                 \
  788.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x5C .. 0x5F */    \
  789.                                                                                                                                                 \
  790.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x60 .. 0x63 */    \
  791.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x64 .. 0x67 */    \
  792.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x68 .. 0x6B */    \
  793.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x6C .. 0x6F */    \
  794.                                                                                                                                                 \
  795.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x70 .. 0x73 */    \
  796.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x74 .. 0x77 */    \
  797.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x78 .. 0x7B */    \
  798.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode    /* 0x7C .. 0x7F */
  799.  
  800.  
  801.  
  802. /* =========================================================================================== */
  803. /* RelocBySectDWithSkip Instruction */
  804. /* -------------------------------- */
  805.  
  806.  
  807.  
  808. /* -------------------------------------------------------------------------------------------    */
  809. /* The "RelocBySectDWithSkip" instruction has the following bit field layout.                    */
  810. /*                                                                                                 */
  811. /*                             1         1                                                        */
  812. /*         0 1 2             9 0         5                                                        */
  813. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  814. /*        |0 0| skip count    | rel count |                                                        */
  815. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  816. /*        | 2 |<-- 8 bits --->|<--  6 --->|                                                        */
  817. /*                                                                                                 */
  818. /* ! Note that the stored skip count and reloc count are the actual values!                        */
  819.  
  820.  
  821. enum {
  822.     kPEFRelocWithSkipMaxSkipCount = 255,
  823.     kPEFRelocWithSkipMaxRelocCount = 63
  824. };
  825.  
  826. #define PEFRelocWithSkipSkipCount(chunk)    PEFRelocField ( (chunk), 2, 8 )
  827. #define PEFRelocWithSkipRelocCount(chunk)    PEFRelocField ( (chunk), 10, 6 )
  828.  
  829. #define PEFRelocComposeWithSkip(skipCount,relocCount)    \
  830.             ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  831.  
  832.  
  833.  
  834. /* =========================================================================================== */
  835. /* RelocRun Group */
  836. /* -------------- */
  837.  
  838.  
  839.  
  840. /* -------------------------------------------------------------------------------------------    */
  841. /* The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            */
  842. /* "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        */
  843. /* following bit field layout.                                                                    */
  844. /*                                                                                                 */
  845. /*                                       1                                                        */
  846. /*         0   2 3     6 7               5                                                        */
  847. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  848. /*        |0 1 0| subop.| run length      |                                                        */
  849. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  850. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        */
  851. /*                                                                                                 */
  852. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the    */
  853. /* ! actual value!                                                                                */
  854.  
  855.  
  856. enum {
  857.     kPEFRelocRunMaxRunLength    = 512
  858. };
  859.  
  860. #define PEFRelocRunSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  861. #define PEFRelocRunRunLength(chunk)    (PEFRelocField ( (chunk), 7, 9 ) + 1)
  862.  
  863. #define PEFRelocComposeRun(subopcode,runLength)    \
  864.             ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  865.  
  866. #define PEFRelocComposeBySectC(runLength)        PEFRelocComposeRun ( 0, (runLength) )
  867. #define PEFRelocComposeBySectD(runLength)        PEFRelocComposeRun ( 1, (runLength) )
  868. #define PEFRelocComposeTVector12(runLength)        PEFRelocComposeRun ( 2, (runLength) )
  869. #define PEFRelocComposeTVector8(runLength)        PEFRelocComposeRun ( 3, (runLength) )
  870. #define PEFRelocComposeVTable8(runLength)        PEFRelocComposeRun ( 4, (runLength) )
  871. #define PEFRelocComposeImportRun(runLength)        PEFRelocComposeRun ( 5, (runLength) )
  872.  
  873.  
  874.  
  875. /* =========================================================================================== */
  876. /* RelocSmIndex Group */
  877. /* ------------------ */
  878.  
  879.  
  880.  
  881. /* ----------------------------------------------------------------------------------------    */
  882. /* The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                */
  883. /* "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    */
  884. /* field layout.                                                                            */
  885. /*                                                                                             */
  886. /*                                       1                                                    */
  887. /*         0   2 3     6 7               5                                                    */
  888. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  889. /*        |0 1 1| subop.| index           |                                                    */
  890. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  891. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    */
  892. /*                                                                                             */
  893. /* ! Note that the stored index is the actual value!                                        */
  894.  
  895.  
  896. enum {
  897.     kPEFRelocSmIndexMaxIndex    = 511
  898. };
  899.  
  900. #define PEFRelocSmIndexSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  901. #define PEFRelocSmIndexIndex(chunk)        PEFRelocField ( (chunk), 7, 9 )
  902.  
  903. #define PEFRelocComposeSmIndex(subopcode,index)    \
  904.             ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  905.  
  906. #define PEFRelocComposeSmByImport(index)    PEFRelocComposeSmIndex ( 0, (index) )
  907. #define PEFRelocComposeSmSetSectC(index)    PEFRelocComposeSmIndex ( 1, (index) )
  908. #define PEFRelocComposeSmSetSectD(index)    PEFRelocComposeSmIndex ( 2, (index) )
  909. #define PEFRelocComposeSmBySection(index)    PEFRelocComposeSmIndex ( 3, (index) )
  910.  
  911.  
  912.  
  913. /* =========================================================================================== */
  914. /* RelocIncrPosition Instruction */
  915. /* ----------------------------- */
  916.  
  917.  
  918.  
  919. /* -------------------------------------------------------------------------------------------    */
  920. /* The "RelocIncrPosition" instruction has the following bit field layout.                        */
  921. /*                                                                                                 */
  922. /*                                       1                                                        */
  923. /*         0     3 4                     5                                                        */
  924. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  925. /*        |1 0 0 0| offset                |                                                        */
  926. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  927. /*        |<- 4 ->|<-- 12 bits ---------->|                                                        */
  928. /*                                                                                                 */
  929. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the        */
  930. /* ! actual value!                                                                                */
  931.  
  932.  
  933. enum {
  934.     kPEFRelocIncrPositionMaxOffset = 4096
  935. };
  936.  
  937. #define PEFRelocIncrPositionOffset(chunk)    (PEFRelocField ( (chunk), 4, 12 ) + 1)
  938.  
  939. #define PEFRelocComposeIncrPosition(offset)    \
  940.             ( 0x8000 | ((UInt16)((offset)-1)) )
  941.  
  942.  
  943.  
  944. /* =========================================================================================== */
  945. /* RelocSmRepeat Instruction */
  946. /* ------------------------- */
  947.  
  948.  
  949.  
  950. /* -------------------------------------------------------------------------------------------    */
  951. /* The "RelocSmRepeat" instruction has the following bit field layout.                            */
  952. /*                                                                                                 */
  953. /*                                       1                                                        */
  954. /*         0     3 4     7 8             5                                                        */
  955. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  956. /*        |1 0 0 1| chnks | repeat count  |                                                        */
  957. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  958. /*        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        */
  959. /*                                                                                                 */
  960. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    */
  961. /* ! macros deal with the actual values!                                                        */
  962.  
  963.  
  964. enum {
  965.     kPEFRelocSmRepeatMaxChunkCount = 16,
  966.     kPEFRelocSmRepeatMaxRepeatCount = 256
  967. };
  968.  
  969. #define PEFRelocSmRepeatChunkCount(chunk)    (PEFRelocField ( (chunk), 4, 4 ) + 1)
  970. #define PEFRelocSmRepeatRepeatCount(chunk)    (PEFRelocField ( (chunk), 8, 8 ) + 1)
  971.  
  972. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount)    \
  973.             ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  974.  
  975.  
  976.  
  977. /* =========================================================================================== */
  978. /* RelocSetPosition Instruction */
  979. /* ---------------------------- */
  980.  
  981.  
  982.  
  983. /* -------------------------------------------------------------------------------------------    */
  984. /* The "RelocSetPosition" instruction has the following bit field layout.                        */
  985. /*                                                                                                 */
  986. /*                                       1                                   1                    */
  987. /*         0         5 6                 5     0                             5                    */
  988. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  989. /*        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    */
  990. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  991. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  992. /*                                                                                                 */
  993. /* ! Note that the stored offset is the actual value!                                            */
  994.  
  995.  
  996. enum {
  997.     kPEFRelocSetPosMaxOffset    = 0x03FFFFFF                    /* 67,108,863 */
  998. };
  999.  
  1000. #define PEFRelocSetPosOffsetHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1001.  
  1002. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk)    \
  1003.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1004.  
  1005. #define PEFRelocComposeSetPosition(fullOffset)    \
  1006.             ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  1007.  
  1008.  
  1009.  
  1010. /* =========================================================================================== */
  1011. /* RelocLgByImport Instruction */
  1012. /* --------------------------- */
  1013.  
  1014.  
  1015.  
  1016. /* -------------------------------------------------------------------------------------------    */
  1017. /* The "RelocLgByImport" instruction has the following bit field layout.                        */
  1018. /*                                                                                                 */
  1019. /*                                       1                                   1                    */
  1020. /*         0         5 6                 5     0                             5                    */
  1021. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1022. /*        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    */
  1023. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1024. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  1025. /*                                                                                                 */
  1026. /* ! Note that the stored offset is the actual value!                                            */
  1027.  
  1028.  
  1029. enum {
  1030.     kPEFRelocLgByImportMaxIndex    = 0x03FFFFFF                    /* 67,108,863 */
  1031. };
  1032.  
  1033. #define PEFRelocLgByImportIndexHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1034.  
  1035. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk)    \
  1036.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1037.  
  1038. #define PEFRelocComposeLgByImport(fullIndex)    \
  1039.             ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1040.  
  1041.  
  1042.  
  1043. /* =========================================================================================== */
  1044. /* RelocLgRepeat Instruction */
  1045. /* ------------------------- */
  1046.  
  1047.  
  1048.  
  1049. /* -------------------------------------------------------------------------------------------    */
  1050. /* The "RelocLgRepeat" instruction has the following bit field layout.                            */
  1051. /*                                                                                                 */
  1052. /*                             1         1                                   1                    */
  1053. /*         0         5 6     9 0         5     0                             5                    */
  1054. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1055. /*        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    */
  1056. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1057. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1058. /*                                                                                                 */
  1059. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        */
  1060. /* ! the actual value!  The stored repeat count is the actual value!                            */
  1061.  
  1062.  
  1063. enum {
  1064.     kPEFRelocLgRepeatMaxChunkCount = 16,
  1065.     kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF                /* 4,194,303 */
  1066. };
  1067.  
  1068. #define PEFRelocLgRepeatChunkCount(chunk)        (PEFRelocField ( (chunk), 6, 4 ) + 1)
  1069. #define PEFRelocLgRepeatRepeatCountHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1070.  
  1071. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk)    \
  1072.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1073.  
  1074. #define PEFRelocComposeLgRepeat(chunkCount,fullRepeatCount)    \
  1075.             ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  1076.  
  1077.  
  1078.  
  1079. /* =========================================================================================== */
  1080. /* RelocLgSetOrBySection Group */
  1081. /* --------------------------- */
  1082.  
  1083.  
  1084.  
  1085. /* -------------------------------------------------------------------------------------------    */
  1086. /* The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    */
  1087. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        */
  1088. /* field layout.                                                                                */
  1089. /*                                                                                                 */
  1090. /*                             1         1                                   1                    */
  1091. /*         0         5 6     9 0         5     0                             5                    */
  1092. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1093. /*        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    */
  1094. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1095. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1096. /*                                                                                                 */
  1097. /* ! Note that the stored index is the actual value!                                            */
  1098.  
  1099.  
  1100. enum {
  1101.     kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF                /* 4,194,303 */
  1102. };
  1103.  
  1104. #define PEFRelocLgSetOrBySectionSubopcode(chunk)    PEFRelocField ( (chunk), 6, 4 )
  1105. #define PEFRelocLgSetOrBySectionIndexHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1106.  
  1107. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk)    \
  1108.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1109.  
  1110. #define PEFRelocComposeLgSetOrBySection(subopcode,fullIndex)    \
  1111.             ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullCount)) >> 16) ) )
  1112.  
  1113. #define PEFRelocComposeLgBySection(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  1114. #define PEFRelocComposeLgSetSectC(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  1115. #define PEFRelocComposeLgSetSectD(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  1116.  
  1117.  
  1118.  
  1119. #if PRAGMA_STRUCT_ALIGN
  1120.     #pragma options align=reset
  1121. #elif PRAGMA_STRUCT_PACKPUSH
  1122.     #pragma pack(pop)
  1123. #elif PRAGMA_STRUCT_PACK
  1124.     #pragma pack()
  1125. #endif
  1126.  
  1127. #ifdef PRAGMA_IMPORT_OFF
  1128. #pragma import off
  1129. #elif PRAGMA_IMPORT
  1130. #pragma import reset
  1131. #endif
  1132.  
  1133. #ifdef __cplusplus
  1134. }
  1135. #endif
  1136.  
  1137. #endif /* __PEFBINARYFORMAT__ */
  1138.  
  1139.